import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import typeconvert.TypeConverterProvider;

import java.sql.Driver;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;

/**
 * 代码生成
 */
public class CodeGenerator {

    /**
     * 生成代码输出路径
     */
    public static final String OUTPUT_PATH = "target\\gen-codes";
    /**
     * 数据库url
     */
    public static final String DATABASE_URL = "jdbc:mysql://10.50.83.52:3306/yuanhang?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&serverTimezone=GMT%2B8";

    /**
     * 数据库用户名
     */
    public static final String USERNAME = "myusername";

    /**
     * 数据库密码
     */
    public static final String PASSWORD = "mypassword";

    /**
     * 生成代码包路径
     */
    public static final String PACKAGE = "com.example.xx";
    /**
     * 需要生成的表，如果不填则生成所有
     */
    public static final String[] INCLUDE_TABLE = new String[]{
    };

    /**
     * 表前缀，添加后生成器会自动删除前缀
     */
    public static final String[] TABLE_PREFIX = new String[]{""};

    /**
     * SQLServer 生成演示
     */
    public static void main(String[] args) {
        System.out.println("=================开始生成代码=================");

        DbType dbType = guessDbType(DATABASE_URL);

        // 自定义需要填充的字段
        List<TableFill> tableFillList = new ArrayList<>();
//        tableFillList.add(new TableFill("create_time", FieldFill.INSERT));
//        tableFillList.add(new TableFill("update_time", FieldFill.INSERT_UPDATE));

        // 代码生成器全局配置
        AutoGenerator mpg = new AutoGenerator().setGlobalConfig(
                // 全局配置
                new GlobalConfig().setOutputDir(OUTPUT_PATH)// 输出目录
                        .setFileOverride(true)// 是否覆盖文件
                        .setActiveRecord(false)// 开启 activeRecord 模式
//						.setEntityName("%sEntity")//实体名
                        .setAuthor("")//作者
                        .setSwagger2(false)//swagger注解
        );


        // 数据源配置
        mpg.setDataSource(
                // 数据源配置
                new DataSourceConfig().setDbType(dbType) // 数据库类型
                        .setTypeConvert(TypeConverterProvider.getTypeConvert(dbType))
                        .setDriverName(Driver.class.getName())
                        .setUsername(USERNAME)
                        .setPassword(PASSWORD)
                        .setUrl(DATABASE_URL)
        );

        // 策略配置
        mpg.setStrategy(
                // 策略配置
                new StrategyConfig()
                        .setTablePrefix(TABLE_PREFIX)// 此处可以修改为您的表前缀
                        .setNaming(NamingStrategy.underline_to_camel)// 表名生成策略
                        // 指定需要生成的表，如果数组没有值则生成所有的表
                        .setInclude(
                                Optional.of(INCLUDE_TABLE)
                                        .flatMap(new Function<String[], Optional<String[]>>() {
                                            @Override
                                            public Optional<String[]> apply(String[] strings) {
                                                return strings.length > 0 ? Optional.of(strings) : Optional.empty();
                                            }
                                        }).orElseGet(() -> new String[]{})
                        )
                        .setTableFillList(tableFillList)
                        .setEntityBooleanColumnRemoveIsPrefix(true)
                        // 生成controller
                        .setRestControllerStyle(false)
                        .setEntitySerialVersionUID(false)
                        .setVersionFieldName("version")
                        .setLogicDeleteFieldName("deleted")
        );

        mpg.setPackageInfo(
                // 包配置
                new PackageConfig().setParent(PACKAGE)// 自定义包路径
        );

        //定制模板
        TemplateConfig templateConfig = new TemplateConfig();
//        String TEMPLATE_SERVICE = "/my-templates/service.java";
//        String TEMPLATE_SERVICE_IMPL = "/my-templates/serviceImpl.java";
//        templateConfig.setService(TEMPLATE_SERVICE);
//        templateConfig.setServiceImpl(TEMPLATE_SERVICE_IMPL);
        mpg.setTemplate(templateConfig);
        FreemarkerTemplateEngine freemarkerTemplateEngine = new FreemarkerTemplateEngine();
        mpg.setTemplateEngine(freemarkerTemplateEngine);

        mpg.execute();
        System.out.println("=================生成代码结束=================");
    }

    private static DbType guessDbType(String dbUrl) {

        if (StringUtils.isEmpty(dbUrl)) {
            throw new RuntimeException("dbUrl未配置");
        }

        //根据URL猜DB TYPE
        DbType dbType = DbType.MYSQL;
        if (dbUrl.contains("mysql")) {
            dbType = DbType.MYSQL;
        } else if (dbUrl.contains("oracle")) {
            dbType = DbType.ORACLE;
        } else {
            throw new RuntimeException("未知数据库类型: " + dbUrl);
        }

        return dbType;
    }


}

